//
// Created by WangPeng on 2024/8/15.
//

#include <iostream>
#include <sys/socket.h>
#include "poller.h"
#include "../rtsp_protocol/rtsp_protocol.h"
#include "../socket/serv_sk.h"

CPoller::CPoller()
{
    serv_ = std::make_unique<CServSocket>("192.168.3.65", 8554);
}

CPoller::~CPoller() = default;

int CPoller::start_rtsp_serv()
{
    nfds_ = 2;
    fds_[0].events = POLLIN;
    fds_[0].fd = serv_->serv_fd();
    std::unique_ptr<CRtspCommand> rtsp_cmd = std::make_unique<CRtspCommand>();
    while (!stop_)
    {
        int num_ready = ::poll(fds_, nfds_, timeout_);
        std::cout << "poll return value = " << num_ready << std::endl;
        if (num_ready <= 0) continue;
        for (int i = 0; i < nfds_; i++)
        {
            if (fds_[i].revents & POLLIN)
            {
                //处理新的连接
                if (serv_->serv_fd() == fds_[i].fd)
                {
                    //默认一个客户端连接
                    std::cout << "receive client connect..." << std::endl;
                    int client_fd = serv_->accept_conn();
                    std::cout << "receive client fd = " << client_fd << std::endl;
                    fds_[1].fd = client_fd;
                    fds_[1].events = POLLIN;
                    continue;
                }
                else
                {
                    std::string data = read_from_fd(fds_[i].fd);
                    std::cout << "receive data/command from: " << fds_[i].fd
                              << ", data is:\n" << data << std::endl;
                    const std::string& ip = serv_->get_string_ip(fds_[i].fd);
                    std::string response = rtsp_cmd->response(data, ip);
                    std::cout << "response = " << response << std::endl;
                    send_all(fds_[i].fd, response);
                    rtsp_cmd->loop_play("/home/licks/h264/test.aac");
                }
            }
        }
    }
    return 0;
}

std::string CPoller::read_from_fd(int fd)
{
    const size_t buffer_size = 4096;  // 每次读取的缓冲区大小
    char buffer[buffer_size] = {0};         // 临时缓冲区
    std::string result;               // 最终存储数据的字符串

    ssize_t bytes_received;           // 每次读取的字节数

    // 循环读取数据直到 recv() 返回 0 或者出现错误
    while ((bytes_received = ::recv(fd, buffer, buffer_size, 0)) > 0)
    {
        result.append(buffer, bytes_received);  // 将缓冲区的数据附加到结果字符串中
    }
    //std::cout << "result = " << result << std::endl;
    return result;
}

int CPoller::send_all(int fd, const std::string &response)
{
    size_t total_sent = 0;  // 已发送的字节数
    size_t data_size = response.size();  // 要发送的数据的总大小
    const char* data_ptr = response.c_str();  // 指向字符串数据的指针

    // 循环发送数据，直到所有数据发送完毕
    while (total_sent < data_size)
    {
        ssize_t bytes_sent = ::send(fd, data_ptr + total_sent, data_size - total_sent, 0);

        if (bytes_sent == -1)
        {
            return -1;
        }
        total_sent += bytes_sent;  // 更新已发送的字节数
    }
    return 0;
}
